package com.example.dish.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.admin_api.EmployeeClient;
import com.example.admin_model.dto.EmployeeDTO;
import com.example.dish.controller.CommonController;

import com.example.dish.mapper.DishMapper;
import com.example.dish.service.CategoryService;
import com.example.dish.service.DishFlavorService;
import com.example.dish.service.DishService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.dish_model.dto.DishDTO;
import com.example.dish_model.entity.Category;
import com.example.dish_model.entity.Dish;
import com.example.dish_model.entity.DishFlavor;
import com.example.exceptions.BusinessException;
import com.example.exceptions.enumetation.ResponseEnum;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 菜品管理 服务实现类
 * </p>
 *
 * @author sjz
 * @since 2024-06-30
 */
@Slf4j
@Service
public class DishServiceImpl extends ServiceImpl<DishMapper, Dish> implements DishService {

    @Resource
    private DishFlavorService dishFlavorService;

    @Resource
    private HttpServletRequest request;

    @Resource
    private EmployeeClient employeeClient;

    @Resource
    @Lazy
    private CategoryService categoryService;

    @Resource
    private CommonController commonController;


    /**
     * 新增菜品,需要操作两张表(tb_dish,tb_dish_flavor)分别存储菜品的基本信息和口味信息
     *
     * @param dishDTO
     */
    @Override
    @Transactional //操作多张表都加事务注解
    public void saveDishAndFlavors(DishDTO dishDTO) {

        //操作tb_dish表->基本信息
        dishDTO.setCreateTime(LocalDateTime.now());
        dishDTO.setUpdateTime(LocalDateTime.now());
        this.save(dishDTO);

        //操作tb_dish_flavor表->口味信息
        //1.获取当前菜品Id
        String dishId = dishDTO.getId();
        //2.获取口味信息
        List<DishFlavor> flavors = dishDTO.getFlavors();

        flavors = flavors.stream().map((item) -> {
            item.setDishId(dishId);
            return item;
        }).collect(Collectors.toList());

        dishFlavorService.saveBatch(flavors);
    }


    /**
     * 根据id查询菜品基本信息和口味信息,需要操作两张表(tb_dish,tb_dish_flavor)
     *
     * @param id
     */
    @Override
    @Transactional
    public DishDTO getDishAndFlavorsById(String id) {
        //操作tb_dish表->查询基本信息
        Dish dish = this.getById(id);

        DishDTO dishDTO = new DishDTO();
        //拷贝基本信息到dto
        BeanUtils.copyProperties(dish, dishDTO);

        //操作tb_dish_flavor表->查询口味信息
        LambdaQueryWrapper<DishFlavor> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DishFlavor::getDishId, dish.getId());
        List<DishFlavor> flavors = dishFlavorService.list(wrapper);
        dishDTO.setFlavors(flavors);
        return dishDTO;
    }


    /**
     * 修改菜品信息(基本信息和口味信息),需要操作两张表(tb_dish,tb_dish_flavor)
     *
     * @param dishDTO
     */
    @Override
    @Transactional
    public void updateDishAndFlavors(DishDTO dishDTO) {
        //更新基本字段信息
        dishDTO.setCreateTime(LocalDateTime.now());
        dishDTO.setUpdateTime(LocalDateTime.now());
        this.updateById(dishDTO);

        //更新口味信息-->先删除原来的
        LambdaQueryWrapper<DishFlavor> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DishFlavor::getDishId, dishDTO.getId());
        dishFlavorService.remove(wrapper);
        //再插入新的口味信息
        List<DishFlavor> flavors = dishDTO.getFlavors();
        flavors = flavors.stream().map((item) -> {
            item.setDishId(dishDTO.getId());
            return item;
        }).collect(Collectors.toList());
        dishFlavorService.saveBatch(flavors);
    }

    @Override
    public List<Dish> getByIds(List<String> ids) {
        LambdaQueryWrapper<Dish> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(Dish::getId, ids);
        List<Dish> dishList = this.list(wrapper);

        return dishList;
    }

    @Override
    public String removeDish(List<String> ids) {
        //校验身份
        EmployeeDTO dto = new EmployeeDTO();
        String token = request.getHeader("Authorization").replace("\"", "");
        dto.setToken(token);
        employeeClient.validate(dto);
        //查询数据库,判断当前菜品的售卖状态(只有已经停售的菜品才可以删除)
        LambdaQueryWrapper<Dish> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(Dish::getId, ids);
        List<Dish> dishList = this.list(wrapper);
        for (Dish dish : dishList) {
            if (dish.getStatus() == 1) {
                throw new BusinessException(ResponseEnum.DISH_DELETE_FAIL);
            }
        }
        this.removeByIds(ids);
        //删除系统指定路径下的图片文件
        for (Dish dish : dishList) {
            //获取图片文件名称
            String img = dish.getImage();
            commonController.deleteImg(img);
        }
        return "菜品删除成功";
    }

    @Override
    public Page<DishDTO> getPage(long page, long pageSize, String name) {

        Page<Dish> pageInfo = new Page<>(page, pageSize);
        //因为dish里面没有categoryName属性,需要DTO
        Page<DishDTO> dishDTOPage = new Page<>();

        LambdaQueryWrapper<Dish> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(name != null, Dish::getName, name);
        wrapper.orderByDesc(Dish::getUpdateTime);
        //执行查询
        this.page(pageInfo, wrapper);
        //把pageInfo拷贝到dishDTOPage中
        BeanUtils.copyProperties(pageInfo, dishDTOPage, "records");

        List<Dish> records = pageInfo.getRecords();
        List<DishDTO> list = records.stream().map((item) -> {
            DishDTO dishDTO = new DishDTO();
            //拷贝基本字段
            BeanUtils.copyProperties(item, dishDTO);
            //分类id
            String categoryId = item.getCategoryId();
            //查询获取分类名称
            Category category = categoryService.getById(categoryId);
            String categoryName = category.getName();
            dishDTO.setCategoryName(categoryName);
            return dishDTO;
        }).collect(Collectors.toList());

        dishDTOPage.setRecords(list);
        return dishDTOPage;
    }
}
